package com.demo.crm.springboot3security.service.impl;

import java.time.LocalDateTime;
import java.util.List;

import com.demo.crm.springboot3security.entity.enums.RelationType;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.demo.crm.springboot3security.entity.FormRelation;
import com.demo.crm.springboot3security.mapper.FormRelationMapper;
import com.demo.crm.springboot3security.service.FormRelationService;
import com.demo.crm.springboot3security.validation.FormRelationValidator;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service
@RequiredArgsConstructor
public class FormRelationServiceImpl implements FormRelationService {

    private final FormRelationMapper formRelationMapper;
    private final FormRelationValidator validator;

    @Override
    @Transactional
    @CacheEvict(cacheNames = { "formRelation", "formRelation_sourceForm", "formRelation_targetForm",
            "formRelation_type" }, allEntries = true)
    public FormRelation save(FormRelation relation) {
        log.info("保存表单关系: {}", relation);
        validator.validateFormRelation(relation);

        if (relation.getId() == null) {
            relation.setCreatedAt(LocalDateTime.now());
            relation.setUpdatedAt(LocalDateTime.now());
            formRelationMapper.insert(relation);
            log.debug("创建新的表单关系，ID: {}", relation.getId());
        } else {
            relation.setUpdatedAt(LocalDateTime.now());
            formRelationMapper.update(relation);
            log.debug("更新表单关系，ID: {}", relation.getId());
        }
        return relation;
    }

    @Override
    @Transactional
    @CacheEvict(cacheNames = { "formRelation", "formRelation_sourceForm", "formRelation_targetForm",
            "formRelation_type" }, allEntries = true)
    public void delete(Long id) {
        log.info("删除表单关系，ID: {}", id);
        formRelationMapper.deleteById(id);
    }

    @Override
    @Cacheable(cacheNames = "formRelation", key = "#id", unless = "#result == null")
    public FormRelation findById(Long id) {
        log.debug("根据ID查找表单关系: {}", id);
        return formRelationMapper.selectOneById(id);
    }

    @Override
    @Cacheable(cacheNames = "formRelation", key = "'all'")
    public List<FormRelation> findAll() {
        log.debug("查找所有表单关系");
        return formRelationMapper.selectAll();
    }

    @Override
    @Cacheable(cacheNames = "formRelation_sourceForm", key = "#sourceFormId")
    public List<FormRelation> findBySourceFormId(Long sourceFormId) {
        log.debug("根据源表单ID查找表单关系: {}", sourceFormId);
        QueryWrapper query = QueryWrapper.create().where("source_form_id = ?", sourceFormId).orderBy("created_at desc");
        return formRelationMapper.selectListByQuery(query);
    }

    @Override
    @Cacheable(cacheNames = "formRelation_targetForm", key = "#targetFormId")
    public List<FormRelation> findByTargetFormId(Long targetFormId) {
        log.debug("根据目标表单ID查找表单关系: {}", targetFormId);
        QueryWrapper query = QueryWrapper.create().where("target_form_id = ?", targetFormId).orderBy("created_at desc");
        return formRelationMapper.selectListByQuery(query);
    }

    @Override
    public Page<FormRelation> findByPage(int pageNumber, int pageSize) {
        log.debug("分页查找表单关系: 页码={}, 每页大小={}", pageNumber, pageSize);
        return formRelationMapper.paginate(pageNumber, pageSize, QueryWrapper.create());
    }

    @Override
    @Transactional
    @CacheEvict(cacheNames = { "formRelation", "formRelation_sourceForm", "formRelation_targetForm",
            "formRelation_type" }, allEntries = true)
    public void deleteBySourceFormId(Long sourceFormId) {
        log.info("删除源表单相关的所有关系，源表单ID: {}", sourceFormId);
        QueryWrapper query = QueryWrapper.create().where("source_form_id = ?", sourceFormId);
        formRelationMapper.deleteByQuery(query);
    }

    @Override
    @Transactional
    @CacheEvict(cacheNames = { "formRelation", "formRelation_sourceForm", "formRelation_targetForm",
            "formRelation_type" }, allEntries = true)
    public void deleteByTargetFormId(Long targetFormId) {
        log.info("删除目标表单相关的所有关系，目标表单ID: {}", targetFormId);
        QueryWrapper query = QueryWrapper.create().where("target_form_id = ?", targetFormId);
        formRelationMapper.deleteByQuery(query);
    }

    @Override
    @Transactional
    @CacheEvict(cacheNames = { "formRelation", "formRelation_sourceForm", "formRelation_targetForm",
            "formRelation_type" }, allEntries = true)
    public List<FormRelation> saveAll(List<FormRelation> relations) {
        log.info("批量保存{}个表单关系", relations.size());
        validator.validateBatchOperation(relations);

        LocalDateTime now = LocalDateTime.now();
        for (FormRelation relation : relations) {
            validator.validateFormRelation(relation);
            if (relation.getId() == null) {
                relation.setCreatedAt(now);
                relation.setUpdatedAt(now);
                formRelationMapper.insert(relation);
                log.debug("创建新的表单关系，ID: {}", relation.getId());
            } else {
                relation.setUpdatedAt(now);
                formRelationMapper.update(relation);
                log.debug("更新表单关系，ID: {}", relation.getId());
            }
        }
        return relations;
    }

    @Override
    @Cacheable(cacheNames = "formRelation", key = "'source:' + #sourceFormId + ':target:' + #targetFormId")
    public List<FormRelation> findBySourceFormIdAndTargetFormId(Long sourceFormId, Long targetFormId) {
        log.debug("查找特定源表单和目标表单之间的关系: 源表单ID={}, 目标表单ID={}", sourceFormId, targetFormId);
        QueryWrapper query = QueryWrapper.create().where("source_form_id = ?", sourceFormId)
                .and("target_form_id = ?", targetFormId).orderBy("created_at desc");
        return formRelationMapper.selectListByQuery(query);
    }

    @Override
    @Cacheable(cacheNames = "formRelation_type", key = "'source:' + #sourceFormId + ':type:' + #relationType")
    public List<FormRelation> findBySourceFormIdAndType(Long sourceFormId, RelationType relationType) {
        log.debug("查找源表单的特定类型关系: 源表单ID={}, 关系类型={}", sourceFormId, relationType);
        validator.validateRelationType(relationType);
        QueryWrapper query = QueryWrapper.create().where("source_form_id = ?", sourceFormId).and("relation_type = ?",
                relationType);
        return formRelationMapper.selectListByQuery(query);
    }

    @Override
    @Cacheable(cacheNames = "formRelation_type", key = "'target:' + #targetFormId + ':type:' + #relationType")
    public List<FormRelation> findByTargetFormIdAndType(Long targetFormId, RelationType relationType) {
        log.debug("查找目标表单的特定类型关系: 目标表单ID={}, 关系类型={}", targetFormId, relationType);
        validator.validateRelationType(relationType);
        QueryWrapper query = QueryWrapper.create().where("target_form_id = ?", targetFormId).and("relation_type = ?",
                relationType);
        return formRelationMapper.selectListByQuery(query);
    }

    @Override
    public boolean existsBySourceAndTargetForm(Long sourceFormId, Long targetFormId) {
        log.debug("检查源表单和目标表单之间是否存在关系: 源表单ID={}, 目标表单ID={}", sourceFormId, targetFormId);
        QueryWrapper query = QueryWrapper.create().where("source_form_id = ?", sourceFormId).and("target_form_id = ?",
                targetFormId);
        return formRelationMapper.selectCountByQuery(query) > 0;
    }

    @Override
    @Transactional
    @CacheEvict(cacheNames = { "formRelation", "formRelation_sourceForm", "formRelation_targetForm",
            "formRelation_type" }, allEntries = true)
    public void batchCreate(List<FormRelation> relations) {
        log.info("批量创建{}个表单关系", relations.size());
        validator.validateBatchOperation(relations);

        LocalDateTime now = LocalDateTime.now();
        for (FormRelation relation : relations) {
            validator.validateFormRelation(relation);
            relation.setCreatedAt(now);
            relation.setUpdatedAt(now);
        }
        formRelationMapper.insertBatch(relations);
    }

    @Override
    @Transactional
    @CacheEvict(cacheNames = { "formRelation", "formRelation_sourceForm", "formRelation_targetForm",
            "formRelation_type" }, allEntries = true)
    public void batchUpdate(List<FormRelation> relations) {
        log.info("批量更新{}个表单关系", relations.size());
        validator.validateBatchOperation(relations);

        LocalDateTime now = LocalDateTime.now();
        for (FormRelation relation : relations) {
            validator.validateFormRelation(relation);
            relation.setUpdatedAt(now);
            formRelationMapper.update(relation);
        }
    }

    @Override
    @Transactional
    @CacheEvict(cacheNames = { "formRelation", "formRelation_sourceForm", "formRelation_targetForm",
            "formRelation_type" }, allEntries = true)
    public void batchDelete(List<Long> ids) {
        if (ids != null && !ids.isEmpty()) {
            log.info("批量删除{}个表单关系", ids.size());
            formRelationMapper.deleteBatchByIds(ids);
        }
    }
}